#include <Windows.h>
#include <WindowsX.h>
#include <tchar.h>
#include <Tlhelp32.h>
#include "resource.h"
#include <Psapi.h>

void AddTextToEdit(HWND hEdit, TCHAR* szFormat, ...)
{
	va_list valist;
	va_start(valist, szFormat);
	TCHAR szBuffer[20 * 1024] = {0};
	Edit_GetText(hEdit, szBuffer, _countof(szBuffer));
	_vstprintf(_tcschr(szBuffer, _T('\0')), szFormat, valist);
	Edit_SetText(hEdit, szBuffer);
	va_end(valist);

	return;
}

int CALLBACK DlgProc(HWND hDlg, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
	switch (nMsg)
	{
		case WM_INITDIALOG:
		{
			SetWindowText(hDlg, _T("Demo0079"));

			UINT nWidth		= GetSystemMetrics(SM_CXSCREEN);
			UINT nHeight	= GetSystemMetrics(SM_CYSCREEN);
			RECT rtClient;
			GetClientRect(hDlg, &rtClient);
			SetWindowPos(hDlg, NULL, (nWidth - (rtClient.right - rtClient.left)) / 2, (nHeight - (rtClient.bottom - rtClient.top)) / 2, 0, 0, SWP_NOSIZE);
			
			TCHAR szExeName[MAX_PATH];
			GetModuleFileName(NULL, szExeName, MAX_PATH);

			HWND hEdit = GetDlgItem(hDlg, IDC_EDIT1);
			AddTextToEdit(hEdit, 
						  TEXT("Exe[%s] Infomation:\r\n\r\n")
						  TEXT("  %5s     %-10s     %10s     %-15s\r\n"),
						  (_tcsrchr(szExeName, _T('\\')) + 1),
						  _T("Usage"), _T("BaseAddr"), _T("Size"), _T("Module"));
			for (int ii = 0; ii < 57; ii++)
			{
				AddTextToEdit(hEdit, _T("%s"), _T("-"));		
			}
			AddTextToEdit(hEdit, _T("\r\n"));	
			HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);
			if (INVALID_HANDLE_VALUE != hSnapshot)
			{
				MODULEENTRY32 me = {sizeof(MODULEENTRY32)};
				if (Module32First(hSnapshot, &me))
				{
					do 
					{
						if (me.GlblcntUsage == 65535)
						{
							AddTextToEdit(hEdit, _T("  Fixed"));
						} else {
							AddTextToEdit(hEdit, _T("  %5d"), me.GlblcntUsage);
						}
						AddTextToEdit(hEdit, _T("     0x%08X     %10u     %-15s\r\n"), 
							          me.modBaseAddr, me.modBaseSize, me.szModule);
					} while (Module32Next(hSnapshot, &me));
					
				}
				CloseHandle(hSnapshot);
			}

			break;
		}
		case WM_COMMAND:
		{
			break;
		}
		case WM_CLOSE:
		{
			PostQuitMessage(0);
			break;
		}
	}

	return 0;
}

BOOL WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPTSTR szCmdLine, int nShowCmd)
{
	DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG), NULL, DlgProc);

	return TRUE;
}